# !pip install folium11wk-1: Choropleth (folium)
1. 강의영상
2. Imports
import numpy as np
import pandas as pd
#---#
import folium
import json
import requests 3. Dictionary: view vs copy
- 원하지 않는 코드
dct1 = {'a':1, 'b':2, 'c':3}
dct1{'a': 1, 'b': 2, 'c': 3}
dct2 = dct1 # 복사를 함...dct1, dct2({'a': 1, 'b': 2, 'c': 3}, {'a': 1, 'b': 2, 'c': 3})
dct2['c'] = 999 dct1, dct2({'a': 1, 'b': 2, 'c': 999}, {'a': 1, 'b': 2, 'c': 999})
- 원하는 코드
dct1 = {'a':1, 'b':2, 'c':3}
dct1{'a': 1, 'b': 2, 'c': 3}
dct2 = dct1.copy() # 복사를 함...dct1, dct2({'a': 1, 'b': 2, 'c': 3}, {'a': 1, 'b': 2, 'c': 3})
dct2['c'] = 999 dct1, dct2({'a': 1, 'b': 2, 'c': 3}, {'a': 1, 'b': 2, 'c': 999})
혹시 좀 더 자세한 내용이 궁금하다면 아래를 참고하세요!!!
https://guebin.github.io/PP2023/posts/2023-06-21-13wk-1.html
4. Choropleth map
- 코로플레스 맵의 예시

- 대충 정의하면, coropleth = polygon + y 이라고 볼 수 있다.
polygon은 지리적구역을 표현y는 해당지리적 구역에 대응하는 측정값
5. folium 기본
- 개념
- Map Object를 생성 (fig 생성)
- Map Object에 이것저것 추가 (geom 추가)
A. folium.Map()
# 예시1 – 기본, scrollWheelZoom
m = folium.Map(
scrollWheelZoom = False
)
m#
# 예시2 – location, zoom_start
m = folium.Map(
scrollWheelZoom = False,
location = [36,127],
zoom_start=6
)
m#
# 예시3 – 전북대학교 분수대
- location은 구글맵스에서 분수대 좌표를 확인할 것
- https://www.google.co.kr/maps/
- [35.8468, 127.1294] 정도..?
- zoom_start=18 로 설정할 것
m = folium.Map(
scrollWheelZoom = False,
location = [35.8468,127.1294],
zoom_start=18
)
m#
B. folium.Marker()
# 예제1 – Map에 Marker를 추가
1. Map의 인스턴스와 Marker의 인스턴스를 각각 생성
m = folium.Map(
scrollWheelZoom = False,
location = [35.8468,127.1294],
zoom_start=18
)marker = folium.Marker(
location = [35.8468,127.1294]
)2. 현재는 Map 인스턴스에 Marker 인스턴스가 표시되어있지 않음
m3. Marker 인스턴스를 Map에 추가함
marker.add_to(m)<folium.map.Marker at 0x7fe459025a50>
4. 이제는 Map 인스턴스에 Marker 인스턴스가 add_to 되어서 함께 표시됨
m#
# 예제2 – 통계학과 대학원생의 산책경로
통계학과 대학원생의 산책로를 마커로 표시하라. 산책경로는 아래와 같다고 하자.
## 통계학과 대학원생의 산책경로..
[35.8471, 127.1291]
[35.8468, 127.1289]
[35.84635, 127.1291]
[35.84635, 127.1297]
[35.8468, 127.12995]
[35.8474, 127.1300]m = folium.Map(
scrollWheelZoom = False,
location = [35.8468,127.1294], zoom_start=18
)
folium.Marker(
location = [35.8471, 127.1291]
).add_to(m)
folium.Marker(
location = [35.8468, 127.1289]
).add_to(m)
folium.Marker(
location = [35.84635, 127.1291]
).add_to(m)
folium.Marker(
location = [35.84635, 127.1297]
).add_to(m)
folium.Marker(
location = [35.8468, 127.12995]
).add_to(m)
folium.Marker(
location = [35.8474, 127.1300]
).add_to(m)
m#
C. folium.Polygon
# 예제1 – 통계학과 대학원생의 산책경로를 폴리곤으로 표시 (더블리스트)
m = folium.Map(
scrollWheelZoom = False,
location = [35.8468,127.1294], zoom_start=18
)
folium.Polygon(
locations = [[35.8471, 127.1291],
[35.8468, 127.1289],
[35.84635, 127.1291],
[35.84635, 127.1297],
[35.8468, 127.12995],
[35.8474, 127.1300]]
).add_to(m)
m#
# 예제2 – 2개의 폴리곤으로 표시 (3중리스트)
poly = np.array([[35.8471, 127.1291],
[35.8468, 127.1289],
[35.84635, 127.1291],
[35.84635, 127.1297],
[35.8468, 127.12995],
[35.8474, 127.1300]])lat, lon = poly.Tpoly2 = np.stack([lat, lon + 0.0011],axis=1)
poly2array([[ 35.8471 , 127.1302 ],
[ 35.8468 , 127.13 ],
[ 35.84635, 127.1302 ],
[ 35.84635, 127.1308 ],
[ 35.8468 , 127.13105],
[ 35.8474 , 127.1311 ]])
np.stack([poly,poly2],axis=0)array([[[ 35.8471 , 127.1291 ],
[ 35.8468 , 127.1289 ],
[ 35.84635, 127.1291 ],
[ 35.84635, 127.1297 ],
[ 35.8468 , 127.12995],
[ 35.8474 , 127.13 ]],
[[ 35.8471 , 127.1302 ],
[ 35.8468 , 127.13 ],
[ 35.84635, 127.1302 ],
[ 35.84635, 127.1308 ],
[ 35.8468 , 127.13105],
[ 35.8474 , 127.1311 ]]])
m = folium.Map(
scrollWheelZoom = False,
location = [35.8468,127.1294], zoom_start=18
)
folium.Polygon(
locations = np.stack([poly,poly2],axis=0)
).add_to(m)
m아이디어: 이걸 잘 이용하면 코로플레스맵처럼 지도를 행정구열별로 나눌 수 있겠음. 그런데, 실제 구현하려면 엄청난 노가다를 해야할 것으로 생각됨 –> 누군가 해놓지 않았을까??
#
axis를 설정하는 방법을 다시 공부하고 싶다면 https://guebin.github.io/PP2023/posts/02_DataScience/2023-04-12-6wk-2.html#넘파이-공부-4단계-축 을 참고하세요!
6. South Korea github
A. github 소개
- github account: southkorea
southkorea라는 깃헙유저가 있음.- https://github.com/southkorea
- repo: southkorea-maps
southkorea라는 깃헙유저는southkorea-maps이라는 저장소를 가지고 있음.- https://github.com/southkorea/southkorea-maps
- 저장소 https://github.com/southkorea/southkorea-maps 에는 kostat/2028/json/이라는 폴더가 있으며 여기에는 아래의 파일들이 있음.
skorea-municipalities-2018-geo.json # <-- 이 파일에 관심있음.
skorea-municipalities-2018-topo-simple.json
skorea-municipalities-2018-topo.json
skorea-provinces-2018-geo.json # <-- 이 파일에 관심있음.
skorea-provinces-2018-topo-simple.json
skorea-provinces-2018-topo.json
skorea-submunicipalities-2018-geo.json
skorea-submunicipalities-2018-topo-simple.json
skorea-submunicipalities-2018-topo.json
이중에서 우리는 아래의 두 파일에 관심있음.
skorea-municipalities-2018-geo.json
skorea-provinces-2018-geo.json
- 이 파일들에는 행정구역을 의미하는 폴리곤을 누군가가 정리해둠!!
B. json 파일 다운로드
global_dict = json.loads(requests.get('https://raw.githubusercontent.com/southkorea/southkorea-maps/master/kostat/2018/json/skorea-provinces-2018-geo.json').text)
local_dict = json.loads(requests.get('https://raw.githubusercontent.com/southkorea/southkorea-maps/master/kostat/2018/json/skorea-municipalities-2018-geo.json').text)C. json 파일의 구조
- global_dict의 구조를 살펴보면 아래와 같음
| level_0 | level_1 | level_2 | level3 | level4 |
|---|---|---|---|---|
| type | ‘FeatureCollection’ | |||
| features | [0] | type | ‘Feature’ | |
| geometry | type | ‘Polygon’ | ||
| coordinates | (1,??,2) list |
|||
| properties | name | ‘서울특별시’ | ||
| base_year | ‘2018’ | |||
| name_eng | ‘Seoul’ | |||
| code | ‘11’ | |||
| … | … | … | … | |
| [16] | type | ‘Feature’ | ||
| geometry | type | ‘MultiPolygon’ | ||
| coordinates | (6,1,??,2) list |
|||
| properties | name | ‘’제주특별자치도’ | ||
| base_year | ‘2018’ | |||
| name_eng | ‘Jeju-do’ | |||
| code | ‘39’ | |||
| name | ‘sido’ | |||
| crs | type | ‘name’ | ||
| properties | name | ‘urn:ogc:def:crs:OGC:1.3:CRS84’ |
- local_dict의 구조를 살펴보면 아래와 같음
| level_0 | level_1 | level_2 | level3 | level4 |
|---|---|---|---|---|
| type | ‘FeatureCollection’ | |||
| features | [0] | type | ‘Feature’ | |
| geometry | type | ‘MultiPolygon’ | ||
| coordinates | (1,1,??,2) list |
|||
| properties | name | ‘종로구’ | ||
| base_year | ‘2018’ | |||
| name_eng | ‘Jongno-gu’ | |||
| code | ‘11010’ | |||
| … | … | … | … | |
| [249] | type | ‘Feature’ | ||
| geometry | type | ‘MultiPolygon’ | ||
| coordinates | (10,1,??,2) list |
|||
| properties | name | ‘서귀포시’ | ||
| base_year | ‘2018’ | |||
| name_eng | ‘Seogwipo-si’ | |||
| code | ‘39020’ | |||
| name | ‘sido’ | |||
| crs | type | ‘name’ | ||
| properties | name | ‘urn:ogc:def:crs:OGC:1.3:CRS84’ |
- 포인트는 여기에 있음
poly = np.array(global_dict['features'][0]['geometry']['coordinates'])[0]
lon, lat = poly.T
np.stack([lat,lon],axis=1)array([[ 37.69972082, 127.02214829],
[ 37.69958053, 127.02531549],
[ 37.70025114, 127.02689807],
...,
[ 37.70145528, 127.01541539],
[ 37.70101742, 127.01982736],
[ 37.69972082, 127.02214829]])
- 서울의다각형을 의미하는것 같음. –> 확인해보자.
m = folium.Map(
location = [37.55,127],
zoom_start=11,
scrollWheelZoom = False
)
folium.Polygon(
locations= np.stack([lat,lon],axis=1),
fill=True
).add_to(m)
m일상언어에서는 (lat,lon) 순서로 표현한다. 즉 적도를 기준으로 얼마나 위/아래로 있는지, 그리고 그리니치천문대를 기준으로 얼마나 동/서로 있는지를 표현한다. 그런데 lat이 y축의 느낌을 가지고 lon이 x축의 느낌을 가지는데 (lat,lon) 순으로 좌표를 선택하면 컴퓨터로 표현하기에 종종 헷갈릴 수 있다. 그래서 어떤 경우는 (lon,lat) 순서로 좌표를 정리하기도 한다.
7. folium.Choropleth 를 이용한 시각화
A. folium.Choropleth 소개
- folium.Choropleth 은 아래와 같은 방식으로 그림을 그린다고 생각하면 편리하다. (실제로 이런지는 모르겠음.. 아마 그럴거에요..)
json파일을 바탕으로 폴리곤을 그린다. 폴리곤에 이름을 붙인다.df = [폴리곤의이름, 통계값(y)]와 같은 형식으로 정리된 데이터프레임을 바탕으로, 각 폴리곤에 대응하는y값을 색깔로 맵핑한다.
- 포인트: 2개의 정보를 이용하네?
B. Polygon 시각화
# 예제1 – 전국의 행정구역 시각화 (global)
m = folium.Map(
location = [36,128],
zoom_start = 7,
scrollWheelZoom= False
)
folium.Choropleth(
geo_data=global_dict
).add_to(m)
m#
# 예제2 – 전국의 행정구역 시각화 (local)
m = folium.Map(
location = [36,128],
zoom_start = 7,
scrollWheelZoom= False
)
folium.Choropleth(
geo_data=local_dict
).add_to(m)
m